package com.woniuxy.shiro;

import com.woniuxy.service.ManagerLoginService;
import com.woniuxy.util.JWTUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * @Todo:自定义域
 */
@Component
public class MyRealm extends AuthorizingRealm {
    @Autowired
    ManagerLoginService managerLoginService;

    // 这个需要注意下, 多域模式中, 每个域里面 请自己配置自己的token来源
    // 这里的token是来自 自定义的MyJsonWebToken
    // 必须重写此方法，不然 传的jwt, shiro却使用的是UsernamePasswordToken进行解析,
    // 会报一个错, 你token格式不对(JWT的值是3部分, UsernamePasswordToken只有1节....)
    // 优化过后，根据源码优化，底层不推荐重写 supports方法，所以我们在ShiroConfig中直接setAuthenticationTokenClass来进行自定义MyJsonWebToken的配置

    /**
     * @Todo: 做授权！
     * @param principals
     * @return org.apache.shiro.authz.AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String token=principals.getPrimaryPrincipal()+"";
        String username= JWTUtil.getUsername(token);
        //去数据库查询该用户所有的角色和权限
        Set<String> roles=managerLoginService.findAllRoles(username);
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);

        //授予权限
        Set<String> perms=managerLoginService.findAllPerms(username);
        simpleAuthorizationInfo.setStringPermissions(perms);
        return simpleAuthorizationInfo;
    }



    /**
     * @Todo: 认证
     * @param authenticationToken
     * @return org.apache.shiro.authc.AuthenticationInfo
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        MyJsonWebToken myJsonWebToken= (MyJsonWebToken) authenticationToken;
        String token=myJsonWebToken.getPrincipal()+"";
        String username=JWTUtil.getUsername(token);

        //使用username去数据库查询用户密码
        String password=managerLoginService.findPassword(username);
        boolean verify=JWTUtil.verify(token,username,password);
        if(verify){
            //直接吧token封装进去
            return  new SimpleAuthenticationInfo(token,token,"myRealm");
        }else{
            throw   new AuthenticationException("token已被篡改，请重新登录");
        }

    }
}
